﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace Utility.DataStructure.Octree
{
	public static class OctreeUtility
	{
		public static bool Octant_to_Signs (int octant, out bool x, out bool y, out bool z)
		{
			if (octant < 0 || octant > 7)
			{
				x = true;
				y = true;
				z = true;
				return false;
			}

			x = (octant & 1 << 0) > 0;
			y = (octant & 1 << 1) > 0;
			z = (octant & 1 << 2) > 0;

			return true;
		}

		public static Vector3Int Octant_to_Signs (int octant)
		{
			bool x, y, z;
			if (Octant_to_Signs (octant, out x, out y, out z))
			{
				return new Vector3Int (x ? 1 : -1, y ? 1 : -1, z ? 1 : -1);
			}
			else
			{
				return Vector3Int.zero;
			}
		}

		public static int Signs_to_Octant (bool x, bool y, bool z)
		{
			int octant = 0;
			octant += (x ? 1 : 0) << 0;
			octant += (y ? 1 : 0) << 1;
			octant += (z ? 1 : 0) << 2;
			return octant;
		}

		/// <summary>
		/// get the octant of a localized coord
		/// coord range from (0,0,0) to (1,1,1)
		/// </summary>
		/// <param name="coord"></param>
		/// <returns></returns>
		public static int GetOctant (Vector3 coord)
		{
			return Signs_to_Octant (coord.x >= 0.5f, coord.y >= 0.5f, coord.z >= 0.5f);
		}

		public static Vector3 GetOctantCoord (Vector3 coord)
		{
			return new Vector3 (coord.x * 2 % 1, coord.y * 2 % 1, coord.z * 2 % 1);
		}

		public static Vector3 GetOctantOriginCoord (int octant)
		{
			bool x, y, z;
			Octant_to_Signs (octant, out x, out y, out z);
			return new Vector3 (x ? 0.5f : 0, y ? 0.5f : 0, z ? 0.5f : 0);
		}
	}
}